/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import com.ibm.staf.STAFException;
import com.ibm.staf.STAFHandle;
import com.ibm.staf.STAFMarshallingContext;
import com.ibm.staf.STAFResult;
import exception.BuildNameNotSetException;
import exception.InvalidHostNameException;
import exception.InvalidSTAFCommandException;
import exception.InvalidTestScriptPlaybackCommandException;
import exception.MachineInfoNotCompleteException;
import exception.RFTInstallPathNotFoundException;
import exception.ScriptPlaybackFailureException;
import exception.TestScriptAlreadyExecutedException;
import exception.VMNotSetupException;
import java.util.HashMap;
import java.util.LinkedList;

/**
 *
 * @author think
 */
public class AbstractMachine implements Machine {

    private String rftVersion;
    private STAFHelper stafHelper;
    private String name;
    private String os;
    private String tsProjectArchive;
    private String tsProjectPath;
    private String tsTcPath;
    private String installerPath;

    public String getOs() {
        return os;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public String getTsProjectArchive() {
        return this.tsProjectArchive;
    }

    public String getTsProjectPath() {
        return this.tsProjectPath;
    }

    public String getTsTcPath() {
        return this.tsTcPath;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRFTVersion() {
        if (this.rftVersion == null) {
            return this.stafHelper.getRFTVersion(this.getName());
        } else {
            return this.rftVersion;
        }
    }

    public String getInstallerPath() {
        return this.installerPath;
    }

    public void setInstallerPath(String path) {
        this.installerPath = path;
    }

    public boolean isInfoComplete() {
        if (this.getName() == null || this.getName().trim().equals("")) {
            return false;
        }
        if (this.getTsProjectPath() == null || this.getTsProjectPath().trim().equals("")) {
            return false;
        }
        if (this.getTsProjectArchive() == null || this.getTsProjectArchive().trim().equals("")) {
            return false;
        }
        if (this.getTsTcPath() == null || this.getTsTcPath().trim().equals("")) {
            return false;
        }
        return true;
    }

    public boolean isStarted() {
        System.out.println("abstract method: isStarted");
        throw new UnsupportedOperationException("Should be override.");
    }

    public boolean getProjectArchive() {
        throw new UnsupportedOperationException("Should be override.");
    }

    public boolean extractProjectArchive() {
        throw new UnsupportedOperationException("Should be override.");
    }

    /**
     * @param tsProjectArchive the tsProjectArchive to set
     */
    public void setTsProjectArchive(String tsProjectArchive) {
        this.tsProjectArchive = tsProjectArchive;
    }

    /**
     * @param tsProjectPath the tsProjectPath to set
     */
    public void setTsProjectPath(String tsProjectPath) {
        this.tsProjectPath = tsProjectPath;
    }

    /**
     * @param tsTcPath the tsTcPath to set
     */
    public void setTsTcPath(String tsTcPath) {
        this.tsTcPath = tsTcPath;
    }

    public String getRFTCommand(TestScript script) throws InvalidSTAFCommandException, RFTInstallPathNotFoundException, InvalidHostNameException, MachineInfoNotCompleteException {
        String version = this.getRFTVersion();
        String command;
        if (version.startsWith("6")) {
            command = getCommandStrForRFT6(script);
        } else {
            command = getCommandStrForRFT7(script);
        }
        return command;
    }

    private String getClasspath() {
        return stafHelper.getClassPath(this.getName());
    }

    private String getCommandStrForRFT7(TestScript script) throws InvalidSTAFCommandException, RFTInstallPathNotFoundException, InvalidHostNameException, MachineInfoNotCompleteException {
//        Machine m = machineFactory.getMachine(this.machine);

        String classPath = "\\\"" + this.getClasspath().replace("\\", "\\\\") + "\\\\rational_ft.jar\\\"";
        String dataStore = "\\\"" + this.getTsProjectPath().replace("\\", "\\\\") + "\\\"";
        return "start command \"java -cp " + classPath + " com.rational.test.ft.rational_ft " +
                "-datastore " + dataStore + " -playback " +
                script.getScriptName() + "\" wait returnstdout stderrtostdout";
    }

    private String getCommandStrForRFT6(TestScript script) throws InvalidSTAFCommandException, RFTInstallPathNotFoundException, InvalidHostNameException, MachineInfoNotCompleteException {
        String installDir = getClasspath();
//        Machine m = machineFactory.getMachine(this.machine);
        String dataStore = this.getTsProjectPath();
        String cp = installDir + "\\rational_ft.jar";

        return "start command \"java -Drational_ft.install.dir=\\\"" + installDir.replace("\\", "\\\\") +
                "\\\" -cp \\\"" + cp.replace("\\", "\\\\") + "\\\" com.rational.test.ft.rational_ft " +
                "-datastore \\\"" + dataStore.replace("\\", "\\\\") + "\\\" -playback " + script.getScriptName() +
                "\" wait returnstdout stderrtostdout";
    }

    public boolean runRFTScript(TestScript script) throws
            InvalidSTAFCommandException,
            RFTInstallPathNotFoundException,
            InvalidHostNameException,
            BuildNameNotSetException,
            VMNotSetupException,
            InvalidTestScriptPlaybackCommandException,
            ScriptPlaybackFailureException,
            MachineInfoNotCompleteException {


        STAFHandle handle;
        STAFResult result;
        try {
            handle = new STAFHandle("run script");
            String command = getRFTCommand(script);
//            System.out.println(this.machine+": "+command);
            result = handle.submit2(this.getName(), "process", command);
            handle.unRegister();
            if (result.rc == 0) {
                if (STAFMarshallingContext.isMarshalledData(result.result)) {
                    STAFMarshallingContext mc = STAFMarshallingContext.unmarshall(
                            result.result);
                    HashMap hash = (HashMap) mc.getRootObject();
                    HashMap item = (HashMap) ((LinkedList) hash.get("fileList")).get(0);
                    if (item.get("data").toString().startsWith("Error")) {
                        throw new InvalidSTAFCommandException();
                    } else {
                        String msg = item.get("data").toString();
                        if (this.parseSTAFResultData(msg)) {
//                            if (createServerSideLogFolder() && copyLog()) {
//                                testResultManager.addResult(this.getResult());
                            return true;
//                            }
                        }
                    }
                } else {
                    System.out.println(result.result);

                }
            }
        } catch (STAFException e) {
            e.printStackTrace();
        }
        return false;
    }

    private boolean parseSTAFResultData(String msg) throws InvalidTestScriptPlaybackCommandException, ScriptPlaybackFailureException {
//        System.out.println(msg);
        if (msg.toLowerCase().startsWith("usage: java")) {
            throw new InvalidTestScriptPlaybackCommandException(msg);
        }
        if (msg.toLowerCase().startsWith("script play back failuer")) {
            throw new ScriptPlaybackFailureException(msg);
//        }
//        if (msg.toLowerCase().startsWith("exception occurred during playback of script")){
//            throw new ScriptPlaybackFailureException(msg);
        } else {
            return true;
        }
    }

}
